#ifndef __PipeSocket_h__
#define __PipeSocket_h__

#include <base/types.h>
#include <interfaces/SystemSocket.h>

#include <queue>

using namespace Greatewall::Interface;

namespace Greatewall
{
    namespace Network
    {
        class PipeSocket : SystemSocket
        {
        public:
            PipeSocket(SocketEventMonitor& monitor, SysSockHandler hdl = -1)
                : SystemSocket(monitor, hdl)
            {}

            ~PipeSocket()
            {}

            virtual void
            handleInbound() = 0;

            virtual bool
            handleOutbound() = 0;

            virtual bool
            write(const char* buf, ssize_t& size);

            virtual bool
            read(char*& buf, ssize_t& size);

            // Since we got two file descriptor for a PIPE, it is handled a little
            // differently for pipe sockets.
            static void
            createPipe(SysSockHandler& in, SysSockHandler& out);

            bool
            initPipeSock();

            virtual void
            close();

        private:
            SysSockHandler _in;
            SysSockHandler _out;

            struct OutboundNode
            {
                OutboundNode(const char* buf, ssize_t size)
                {
                    _offset = 0;
                    _size   = size;
                    _buf    = buf;
                }
                ~OutboundNode()
                {
                    delete _buf;
                }

                int         _offset;
                ssize_t     _size;
                const char* _buf;
            };
            std::queue<OutboundNode> _outbound_queue;
            uint64_t aligned_buf[1024*64];
        };
    }
}
#endif
